﻿using System;
using System.Data;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Web;
using System.Web.SessionState;

using System.Runtime;
using System.Runtime.Serialization;
using System.Runtime.InteropServices;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Messaging;

using PickGold.Generic;
using PickGold.Handler;

namespace PickGold.Base.Proxies
{
	/// <summary>
	/// 属性访问器代理
	/// </summary>
	[Serializable]
	public class PropertiesProxy : RealProxy, ISerializable
	{
		private const string KEY_TYPE = "PropertiesProxy_Type";
		private const string KEY_DATA = "PropertiesProxy_Proxy";

		#region inner class for IPropertiesAccessor

		#region StringDictionaryPropertiesAccessor

		[Serializable]
		[ComVisible(true)]
		[ClassInterface(ClassInterfaceType.AutoDispatch)]
		class StringDictionaryPropertiesAccessor : IPropertiesAccessor
		{
			public IDictionary<string, object> Real;

			#region IPropertiesAccessor 成员

			object IPropertiesAccessor.this[object key]
			{
				get
				{
					if (key == null)
						return this.Real[default(string)];

					if (key is string)
						return this.Real[key as string];

					return this.Real[key + string.Empty];
				}
				set
				{
					if (key == null)
						this.Real[default(string)] = value;
					else if (key is string)
						this.Real[key as string] = value;
					else
						this.Real[key + string.Empty] = value;
				}
			}

			bool IPropertiesAccessor.Contains(object key)
			{
				if (key == null)
					return this.Real.ContainsKey(default(string));

				if (key is string)
					return this.Real.ContainsKey(key as string);

				return this.Real.ContainsKey(key + string.Empty);
			}

			bool IPropertiesAccessor.IsReadOnly
			{
				get
				{
					return this.Real.IsReadOnly;
				}
			}

			object IPropertiesAccessor.Real
			{
				get
				{
					return this.Real;
				}
			}

			#endregion
		}

		#endregion

		#region ObjectDictionaryPropertiesAccessor

		[Serializable]
		[ComVisible(true)]
		[ClassInterface(ClassInterfaceType.AutoDispatch)]
		class ObjectDictionaryPropertiesAccessor : IPropertiesAccessor
		{
			public IDictionary<object, object> Real;

			#region IPropertiesAccessor 成员

			object IPropertiesAccessor.this[object key]
			{
				get
				{
					return this.Real[key];
				}
				set
				{
					this.Real[key] = value;
				}
			}

			bool IPropertiesAccessor.Contains(object key)
			{
				return this.Real.ContainsKey(key);
			}

			bool IPropertiesAccessor.IsReadOnly
			{
				get
				{
					return this.Real.IsReadOnly;
				}
			}

			object IPropertiesAccessor.Real
			{
				get
				{
					return this.Real;
				}
			}

			#endregion
		}

		#endregion

		#region OtherDictionaryPropertiesAccessor

		[Serializable]
		[ComVisible(true)]
		[ClassInterface(ClassInterfaceType.AutoDispatch)]
		class OtherDictionaryPropertiesAccessor : IPropertiesAccessor
		{
			public IDictionary Real;

			#region IPropertiesAccessor 成员

			object IPropertiesAccessor.this[object key]
			{
				get
				{
					return this.Real[key];
				}
				set
				{
					this.Real[key] = value;
				}
			}

			bool IPropertiesAccessor.Contains(object key)
			{
				return this.Real.Contains(key);
			}

			bool IPropertiesAccessor.IsReadOnly
			{
				get
				{
					return this.Real.IsReadOnly;
				}
			}

			object IPropertiesAccessor.Real
			{
				get
				{
					return this.Real;
				}
			}

			#endregion
		}

		#endregion

		#region CustomTypeDescriptorPropertiesAccessor

		[Serializable]
		[ComVisible(true)]
		[ClassInterface(ClassInterfaceType.AutoDispatch)]
		class CustomTypeDescriptorPropertiesAccessor : IPropertiesAccessor
		{
			public ICustomTypeDescriptor Real;

			#region IPropertiesAccessor 成员

			object IPropertiesAccessor.this[object key]
			{
				get
				{
					if (key == null)
						return this.Real.GetProperties()[default(string)].GetValue(this.Real);

					if (key is string)
						return this.Real.GetProperties()[key as string].GetValue(this.Real);

					return this.Real.GetProperties()[key + string.Empty].GetValue(this.Real);
				}
				set
				{
					if (key == null)
						this.Real.GetProperties()[default(string)].SetValue(this.Real, value);
					else if (key is string)
						this.Real.GetProperties()[key as string].SetValue(this.Real, value);
					else
						this.Real.GetProperties()[key + string.Empty].SetValue(this.Real, value);
				}
			}

			bool IPropertiesAccessor.Contains(object key)
			{
				if (key == null)
					return this.Real.GetProperties().Find(default(string), true) != null;

				if (key is string)
					return this.Real.GetProperties().Find(key as string, true) != null;

				return this.Real.GetProperties().Find(key + string.Empty, true) != null;
			}

			bool IPropertiesAccessor.IsReadOnly
			{
				get
				{
					return true;
				}
			}

			object IPropertiesAccessor.Real
			{
				get
				{
					return this.Real;
				}
			}

			#endregion
		}

		#endregion

		#region DataRecordPropertiesAccessor

		class DataRecordPropertiesAccessor : IPropertiesAccessor
		{
			public IDataRecord Real;

			#region IPropertiesAccessor 成员

			object IPropertiesAccessor.this[object key]
			{
				get
				{
					if (key == null)
						return this.Real[default(string)];

					if (key is string)
						return this.Real[key as string];

					return this.Real[key + string.Empty];
				}
				set
				{
					throw new NotSupportedException();
				}
			}

			bool IPropertiesAccessor.Contains(object key)
			{
				var k = key as string;
				if (key != null && k == null)
					k = key + string.Empty;
				for (var i = 0; i < this.Real.FieldCount; i++)
				{
					if (string.Compare(this.Real.GetName(i), k, StringComparison.OrdinalIgnoreCase) == 0)
						return true;
				}

				return false;
			}

			bool IPropertiesAccessor.IsReadOnly
			{
				get
				{
					return true;
				}
			}

			object IPropertiesAccessor.Real
			{
				get
				{
					return this.Real;
				}
			}

			#endregion
		}

		#endregion

		#region DataRowPropertiesAccessor

		class DataRowPropertiesAccessor : IPropertiesAccessor
		{
			public DataRow Real;

			#region IPropertiesAccessor 成员

			object IPropertiesAccessor.this[object key]
			{
				get
				{
					if (key == null)
						return this.Real[default(string)];

					if (key is string)
						return this.Real[key as string];

					return this.Real[key + string.Empty];
				}
				set
				{
					if (key == null)
						this.Real[default(string)] = value;
					else if (key is string)
						this.Real[key as string] = value;
					else
						this.Real[key + string.Empty] = value;
				}
			}

			bool IPropertiesAccessor.Contains(object key)
			{
				if (key == null)
					return this.Real.Table.Columns.Contains(default(string));

				if (key is string)
					return this.Real.Table.Columns.Contains(key as string);

				return this.Real.Table.Columns.Contains(key + string.Empty);
			}

			bool IPropertiesAccessor.IsReadOnly
			{
				get
				{
					return false;
				}
			}

			object IPropertiesAccessor.Real
			{
				get
				{
					return this.Real;
				}
			}

			#endregion
		}

		#endregion

		#region NameObjectCollectionPropertiesAccessor

		class NameObjectCollectionPropertiesAccessor : NameObjectCollectionBase, IPropertiesAccessor
		{
			public NameObjectCollectionBase Real;
			private static MethodInfo BaseGetMethod;
			private static MethodInfo BaseSetMethod;
			private static PropertyInfo IsReadOnlyProperty;

			#region IPropertiesAccessor 成员

			object IPropertiesAccessor.this[object key]
			{
				get
				{
					var k = key as string;
					if (key != null && k == null)
						k = key + string.Empty;
					if (BaseGetMethod == null)
						BaseGetMethod = new HByReturnDelegate<object, string>(base.BaseGet).Method;
					return BaseGetMethod.Invoke(this.Real, new object[] { k });
				}
				set
				{
					var k = key as string;
					if (key != null && k == null)
						k = key + string.Empty;
					if (BaseSetMethod == null)
						BaseSetMethod = new HNoReturnDelegate<string, object>(base.BaseSet).Method;
					BaseSetMethod.Invoke(this.Real, new object[] { k, value });
				}
			}

			bool IPropertiesAccessor.Contains(object key)
			{
				var k = key as string;
				if (key != null && k == null)
					k = key + string.Empty;
				foreach (var kk in this.Real.Keys)
				{
					if (string.Compare(kk as string, k, StringComparison.OrdinalIgnoreCase) == 0)
						return true;
				}

				return false;
			}

			bool IPropertiesAccessor.IsReadOnly
			{
				get
				{
					if (IsReadOnlyProperty == null)
					{
						var ps = this.GetType().GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy);
						//IsReadOnlyProperty = this.IsReadOnly;
					}
					return (bool)IsReadOnlyProperty.GetValue(this.Real, null);
				}
			}

			object IPropertiesAccessor.Real
			{
				get
				{
					return this.Real;
				}
			}

			#endregion
		}

		#endregion

		class SurrogateSelector : ISurrogateSelector
		{
			void ISurrogateSelector.ChainSelector(ISurrogateSelector selector)
			{
				throw new NotImplementedException();
			}

			ISurrogateSelector ISurrogateSelector.GetNextSelector()
			{
				throw new NotImplementedException();
			}

			ISerializationSurrogate ISurrogateSelector.GetSurrogate(Type type, StreamingContext context, out ISurrogateSelector selector)
			{
				throw new NotImplementedException();
			}
		}

		#endregion

		[NonSerialized]
		private PropertiesProxyEventHandler _OnInvokeHandler;

		private IPropertiesAccessor _Proxy;

		#region ctor

		/// <summary>
		/// 构造实例化一属性访问代理对象。
		/// </summary>
		/// <param name="type">代理类型。</param>
		protected PropertiesProxy(Type type) : this(type, (IPropertiesAccessor)new OtherDictionaryPropertiesAccessor { Real = new Hashtable() }) { }
		/// <summary>
		/// 构造实例化一属性访问代理对象
		/// </summary>
		/// <param name="type">代理类型</param>
		/// <param name="proxy">被代理的真实对象。</param>
		protected PropertiesProxy(Type type, IPropertiesAccessor proxy)
			: base(type)
		{
			if (proxy == null)
				throw new ArgumentNullException();

			this._Proxy = proxy;
		}
		/// <summary>
		/// 构造实例化一属性访问代理对象。
		/// </summary>
		/// <param name="type">代理类型。</param>
		/// <param name="real">被代理的真实对象。</param>
		protected PropertiesProxy(Type type, IDictionary<string, object> real) : this(type, (IPropertiesAccessor)new StringDictionaryPropertiesAccessor { Real = real }) { }
		/// <summary>
		/// 构造实例化一属性访问代理对象。
		/// </summary>
		/// <param name="type">代理类型。</param>
		/// <param name="real">被代理的真实对象。</param>
		protected PropertiesProxy(Type type, IDictionary<object, object> real) : this(type, (IPropertiesAccessor)new ObjectDictionaryPropertiesAccessor { Real = real }) { }
		/// <summary>
		/// 构造实例化一属性访问代理对象。
		/// </summary>
		/// <param name="type">代理类型。</param>
		/// <param name="real">被代理的真实对象。</param>
		protected PropertiesProxy(Type type, IDictionary real) : this(type, (IPropertiesAccessor)new OtherDictionaryPropertiesAccessor { Real = real }) { }
		/// <summary>
		/// 构造实例化一属性访问代理对象。
		/// </summary>
		/// <param name="type">代理类型。</param>
		/// <param name="real">被代理的真实对象。</param>
		protected PropertiesProxy(Type type, ICustomTypeDescriptor real) : this(type, (IPropertiesAccessor)new CustomTypeDescriptorPropertiesAccessor { Real = real }) { }
		/// <summary>
		/// 构造实例化一属性访问代理对象。
		/// </summary>
		/// <param name="type">代理类型。</param>
		/// <param name="real">被代理的真实对象。</param>
		protected PropertiesProxy(Type type, IDataRecord real) : this(type, (IPropertiesAccessor)new DataRecordPropertiesAccessor { Real = real }) { }
		/// <summary>
		/// 构造实例化一属性访问代理对象。
		/// </summary>
		/// <param name="type">代理类型。</param>
		/// <param name="real">被代理的真实对象。</param>
		protected PropertiesProxy(Type type, DataRow real) : this(type, (IPropertiesAccessor)new DataRowPropertiesAccessor { Real = real }) { }
		/// <summary>
		/// 构造实例化一属性访问代理对象。
		/// </summary>
		/// <param name="type">代理类型。</param>
		/// <param name="real">被代理的真实对象。</param>
		protected PropertiesProxy(Type type, NameObjectCollectionBase real) : this(type, (IPropertiesAccessor)new NameObjectCollectionPropertiesAccessor { Real = real }) { }
		/// <summary>
		/// Populates a System.Runtime.Serialization.SerializationInfo with the data needed to serialize the target object.
		/// </summary>
		/// <param name="info">The System.Runtime.Serialization.SerializationInfo to populate with data.</param>
		/// <param name="context">The destination (see System.Runtime.Serialization.StreamingContext) for this serialization.</param>
		/// <exception cref="System.Security.SecurityException">The caller does not have the required permission.</exception>
		protected PropertiesProxy(SerializationInfo info, StreamingContext context) : this(info.GetValue(KEY_TYPE, typeof(Type)) as Type, info.GetValue(KEY_DATA, typeof(IPropertiesAccessor)) as IPropertiesAccessor) { }

		#endregion

		/// <summary>
		/// 获取真实访问器。
		/// </summary>
		public IPropertiesAccessor RealAccessor
		{
			get
			{
				return this._Proxy;
			}
		}

		/// <summary>
		/// 按成员取键名，但如果代理对象中存在以成员名命名的元素，将以成员名优先
		/// </summary>
		/// <param name="member">检查生成键名的成员</param>
		/// <param name="defaultKey">默认键名，取默认字符串</param>
		/// <returns>键名</returns>
		public object GetMemberKey(object member, object defaultKey)
		{
			var h = member as Delegate;
			if (h != null)
				return this.GetMemberKey(h.Method, defaultKey);

			if (defaultKey == null)
				return this.GetMemberKey(member as MemberInfo, member);

			return this.GetMemberKey(member as MemberInfo, defaultKey);
		}
		/// <summary>
		/// 按成员取键名，但如果代理对象中存在以成员名命名的元素，将以成员名优先
		/// </summary>
		/// <param name="member">检查生成键名的成员</param>
		/// <param name="defaultKey">默认键名，取默认字符串</param>
		/// <returns>键名</returns>
		protected virtual object GetMemberKey(MemberInfo member, object defaultKey)
		{
			if (member == null)
			{
				if (defaultKey is MemberInfo)
					return defaultKey + string.Empty;

				return defaultKey;
			}

			var cas = member.GetCustomAttributes(typeof(PropertiesProxyKeyAttribute), true);//PropertiesProxyKeyAttribute
			if (cas != null && cas.Length > 0)
			{
				var a = cas[0] as PropertiesProxyKeyAttribute;
				if (a != null && a.Key != null)
					return a.Key;
			}

			cas = member.GetCustomAttributes(typeof(DataAttribute), true);//DataAttribute//ColumnAttribute
			if (cas != null && cas.Length > 0)
			{
				var a = cas[0] as DataAttribute;
				if (a != null)
				{
					if (string.IsNullOrEmpty(a.Name))
						return member.Name;

					return a.Name;
				}
			}

			if (defaultKey is MemberInfo)
				return defaultKey + string.Empty;

			return defaultKey;
		}

		#region Invoke

		/// <summary>
		/// 对当前代理类型所表示的代理对象调用在所提供的 System.Runtime.Remoting.Messaging.IMessage 中指定的方法。
		/// </summary>
		/// <param name="msg">System.Runtime.Remoting.Messaging.IMessage，包含有关方法调用的信息的 System.Collections.IDictionary</param>
		/// <returns>调用的方法所返回的消息，包含返回值和所有 out 或 ref 参数。</returns>
		public override IMessage Invoke(IMessage msg)
		{
			var mcm = msg as IMethodCallMessage;
			if (mcm == null)
				return new ReturnMessage(null, null, 0, null, null);

			var e = Reflector.Generic<PropertiesProxyEventArgs>.DefaultValue;
			if (this._OnInvokeHandler != null)
			{
				if (e == null)
					e = new PropertiesProxyEventArgs(mcm);
				this._OnInvokeHandler(this._Proxy.Real, e);
			}
			var outArgs = new object[mcm.ArgCount];
			mcm.Args.CopyTo(outArgs, 0);
			try
			{
				var mrm = this.Invoke(mcm, outArgs);
				if (this._OnInvokeHandler != null)
				{
					if (e == null)
						e = new PropertiesProxyEventArgs(mrm);
					this._OnInvokeHandler(this._Proxy.Real, e);
				}
				return mrm;
			}
			catch (Exception x)
			{
				var mrm = new ReturnMessage(x, mcm);
				if (this._OnInvokeHandler != null)
				{
					if (e == null)
						e = new PropertiesProxyEventArgs(mrm);
					this._OnInvokeHandler(this._Proxy.Real, e);
				}
				return mrm;
			}
		}
		/// <summary>
		/// Try Invoke
		/// </summary>
		/// <param name="mcm"></param>
		/// <param name="outArgs"></param>
		/// <returns></returns>
		private IMethodReturnMessage Invoke(IMethodCallMessage mcm, object[] outArgs)
		{
			if (mcm.MethodBase.MethodHandle == new Func<Type>(this.GetType).Method.MethodHandle)//object::GetType()
				return new ReturnMessage(/*this._Proxy.GetType()*/this.GetProxiedType(), null, 0, null, mcm);//object::GetType()

			var method = mcm.MethodBase;
			if (mcm.MethodBase.DeclaringType == typeof(object))//是否为字段【成员变量】的访问。
			{
				if ((mcm.MethodBase == Reflector.FieldSetter || mcm.MethodBase == Reflector.FieldGetter) &&
					this._Proxy.Real.IsType(mcm.Args[0] as string))
				{
					var rm = mcm.Invoke(this._Proxy.Real, method);
					if (rm != null)
						return rm;
				}
			}
			else if (this._Proxy.Real.IsType(mcm.MethodBase.DeclaringType))//直接访问成员。
			{
				var rm = mcm.Invoke(this._Proxy.Real, method);
				if (rm != null)
					return rm;
			}

			if (this._Proxy is ObjectPropertiesAccessor)//直接成员访问。
			{
				var rm = mcm.Invoke(this._Proxy.Real, string.IsNullOrEmpty(mcm.MethodName) ? method.Name : mcm.MethodName);
				if (rm == null)
					return new ReturnMessage(new NotImplementedException(), mcm);

				return rm;
			}

			var key = this.GetMemberKey(null, method);//如果方法被委托。
			if (this._Proxy.Contains(key))
			{
				var handler = this._Proxy[key] as Delegate;
				if (handler != null)
					return mcm.Invoke(handler.Target, handler.Method);
			}

			var msg = this.Invoke(mcm, method, outArgs);
			if (msg != null)
				return msg;

			return mcm.Invoke(this._Proxy.Real, string.IsNullOrEmpty(mcm.MethodName) ? method.Name : mcm.MethodName);
		}
		/// <summary>
		/// 成员变量或属性访问
		/// </summary>
		/// <param name="mcm"></param>
		/// <param name="outArgs"></param>
		/// <param name="method"></param>
		/// <returns></returns>
		private IMethodReturnMessage Invoke(IMethodCallMessage mcm, MethodBase method, object[] outArgs)
		{
			if (method == Reflector.FieldSetter || method == Reflector.FieldGetter)//成员变量访问
			{
				var type = this.GetProxiedType();//Type.GetType(mcm.Args[0] as string);
				var f = type.GetAllField(mcm.Args[1] as string, true);// type.GetField(mcm.Args[1] as string, BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);// | BindingFlags.FlattenHierarchy
				var key = this.GetMemberKey(f, f);
				if (mcm.Args[2] == null)//Void FieldGetter(System.String, System.String, System.Object ByRef)
				{
					if (this._Proxy.Contains(key))
						outArgs[2] = this._Proxy[key];
					else
						outArgs[2] = f.FieldType.GetDefault();
					return new ReturnMessage(outArgs[2], outArgs, 0, null, mcm);
				}

				this._Proxy[key] = mcm.Args[2];
				return new ReturnMessage(null, outArgs, 0, null, mcm);
			}

			#region 对代理对象的属性（如果是方法则不会成功）访问

			var ps = mcm.MethodBase.DeclaringType.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.FlattenHierarchy);
			foreach (var p in ps)
			{
				var ms = p.GetSetMethod();
				if (ms != null && ms.MethodHandle == mcm.MethodBase.MethodHandle)
				{
					var key = this.GetMemberKey(p, p);
					this._Proxy[key] = mcm.Args[0];
					return new ReturnMessage(null, outArgs, 0, null, mcm);
				}

				var mg = p.GetGetMethod();
				if (mg != null && mg.MethodHandle == mcm.MethodBase.MethodHandle)
				{
					var key = this.GetMemberKey(p, p);
					if (this._Proxy.Contains(key))
						return new ReturnMessage(this._Proxy[key], outArgs, 0, null, mcm);

					return new ReturnMessage(p.PropertyType.GetDefault(), outArgs, 0, null, mcm);
				}
			}

			#endregion

			return null;
		}

		#endregion

		#region ISerializable 成员

		void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
		{
			this.GetObjectData(info, context);
		}

		/// <summary>
		/// Populates a System.Runtime.Serialization.SerializationInfo with the data needed to serialize the target object.
		/// </summary>
		/// <param name="info">The System.Runtime.Serialization.SerializationInfo to populate with data.</param>
		/// <param name="context">The destination (see System.Runtime.Serialization.StreamingContext) for this serialization.</param>
		/// <exception cref="System.Security.SecurityException">The caller does not have the required permission.</exception>
		public override void GetObjectData(SerializationInfo info, StreamingContext context)
		{
			info.AddValue(KEY_TYPE, this.GetProxiedType());
			info.AddValue(KEY_DATA, this._Proxy);
			//base.GetObjectData(info, context);
		}

		#endregion

		#region GetProxy

		/// <summary>
		/// 获取代理
		/// </summary>
		/// <param name="type">代理类型</param>
		/// <returns>属性访问器代理</returns>
		public static object GetProxy(Type type)
		{
			return new PropertiesProxy(type).GetTransparentProxy();
		}
		/// <summary>
		/// 获取代理。
		/// </summary>
		/// <param name="type">代理类型。</param>
		/// <param name="proxy">被代理的真实对象。</param>
		/// <returns>属性访问器代理。</returns>
		public static object GetProxy(Type type, IPropertiesAccessor proxy)
		{
			if (proxy == null)
				return null;

			return new PropertiesProxy(type, proxy).GetTransparentProxy();
		}
		/// <summary>
		/// 获取代理。
		/// </summary>
		/// <param name="type">代理类型。</param>
		/// <param name="proxy">被代理的真实对象。</param>
		/// <returns>属性访问器代理。</returns>
		public static object GetProxy(Type type, IDictionary<string, object> proxy)
		{
			if (proxy == null)
				return null;

			return new PropertiesProxy(type, proxy).GetTransparentProxy();
		}
		/// <summary>
		/// 获取代理。
		/// </summary>
		/// <param name="type">代理类型。</param>
		/// <param name="proxy">被代理的真实对象。</param>
		/// <returns>属性访问器代理。</returns>
		public static object GetProxy(Type type, IDictionary<object, object> proxy)
		{
			if (proxy == null)
				return null;

			return new PropertiesProxy(type, proxy).GetTransparentProxy();
		}
		/// <summary>
		/// 获取代理。
		/// </summary>
		/// <param name="type">代理类型。</param>
		/// <param name="proxy">被代理的真实对象。</param>
		/// <returns>属性访问器代理。</returns>
		public static object GetProxy(Type type, IDictionary proxy)
		{
			if (proxy == null)
				return null;

			return new PropertiesProxy(type, proxy).GetTransparentProxy();
		}
		/// <summary>
		/// 获取代理。
		/// </summary>
		/// <param name="type">代理类型。</param>
		/// <param name="proxy">被代理的真实对象。</param>
		/// <returns>属性访问器代理。</returns>
		public static object GetProxy(Type type, ICustomTypeDescriptor proxy)
		{
			if (proxy == null)
				return null;

			return new PropertiesProxy(type, proxy).GetTransparentProxy();
		}
		/// <summary>
		/// 获取代理。
		/// </summary>
		/// <param name="type">代理类型。</param>
		/// <param name="proxy">被代理的真实对象。</param>
		/// <returns>属性访问器代理。</returns>
		public static object GetProxy(Type type, IDataReader proxy)
		{
			if (proxy == null)
				return null;

			return new PropertiesProxy(type, proxy).GetTransparentProxy();
		}
		/// <summary>
		/// 获取代理。
		/// </summary>
		/// <param name="type">代理类型。</param>
		/// <param name="proxy">被代理的真实对象。</param>
		/// <returns>属性访问器代理。</returns>
		public static object GetProxy(Type type, DataRow proxy)
		{
			if (proxy == null)
				return null;

			return new PropertiesProxy(type, proxy).GetTransparentProxy();
		}
		/// <summary>
		/// 获取代理。
		/// </summary>
		/// <param name="type">代理类型。</param>
		/// <param name="proxy">被代理的真实对象。</param>
		/// <returns>属性访问器代理。</returns>
		public static object GetProxy(Type type, NameObjectCollectionBase proxy)
		{
			if (proxy == null)
				return null;

			return new PropertiesProxy(type, proxy).GetTransparentProxy();
		}

		/// <summary>
		/// 获取代理
		/// </summary>
		/// <typeparam name="REAL">代理类型</typeparam>
		/// <returns>属性访问器代理</returns>
		public static REAL GetProxy<REAL>()
		{
			return (REAL)PropertiesProxy.GetProxy(typeof(REAL));
		}
		/// <summary>
		/// 获取代理。
		/// </summary>
		/// <typeparam name="REAL">代理类型。</typeparam>
		/// <param name="proxy">被代理的真实对象。</param>
		/// <returns>属性访问器代理。</returns>
		public static REAL GetProxy<REAL>(IPropertiesAccessor proxy)
		{
			return (REAL)PropertiesProxy.GetProxy(typeof(REAL), proxy);
		}
		/// <summary>
		/// 获取代理。
		/// </summary>
		/// <typeparam name="REAL">代理类型。</typeparam>
		/// <param name="proxy">被代理的真实对象。</param>
		/// <returns>属性访问器代理。</returns>
		public static REAL GetProxy<REAL>(IDictionary<string, object> proxy)
		{
			return (REAL)PropertiesProxy.GetProxy(typeof(REAL), proxy);
		}
		/// <summary>
		/// 获取代理。
		/// </summary>
		/// <typeparam name="REAL">代理类型。</typeparam>
		/// <param name="proxy">被代理的真实对象。</param>
		/// <returns>属性访问器代理。</returns>
		public static REAL GetProxy<REAL>(IDictionary<object, object> proxy)
		{
			return (REAL)PropertiesProxy.GetProxy(typeof(REAL), proxy);
		}
		/// <summary>
		/// 获取代理。
		/// </summary>
		/// <typeparam name="REAL">代理类型。</typeparam>
		/// <param name="proxy">被代理的真实对象。</param>
		/// <returns>属性访问器代理。</returns>
		public static REAL GetProxy<REAL>(IDictionary proxy)
		{
			return (REAL)PropertiesProxy.GetProxy(typeof(REAL), proxy);
		}
		/// <summary>
		/// 获取代理。
		/// </summary>
		/// <typeparam name="REAL">代理类型。</typeparam>
		/// <param name="proxy">被代理的真实对象。</param>
		/// <returns>属性访问器代理。</returns>
		public static REAL GetProxy<REAL>(ICustomTypeDescriptor proxy)
		{
			return (REAL)PropertiesProxy.GetProxy(typeof(REAL), proxy);
		}
		/// <summary>
		/// 获取代理。
		/// </summary>
		/// <typeparam name="REAL">代理类型。</typeparam>
		/// <param name="proxy">被代理的真实对象。</param>
		/// <returns>属性访问器代理。</returns>
		public static REAL GetProxy<REAL>(IDataReader proxy)
		{
			return (REAL)PropertiesProxy.GetProxy(typeof(REAL), proxy);
		}
		/// <summary>
		/// 获取代理。
		/// </summary>
		/// <typeparam name="REAL">代理类型。</typeparam>
		/// <param name="proxy">被代理的真实对象。</param>
		/// <returns>属性访问器代理。</returns>
		public static REAL GetProxy<REAL>(DataRow proxy)
		{
			return (REAL)PropertiesProxy.GetProxy(typeof(REAL), proxy);
		}
		/// <summary>
		/// 获取代理。
		/// </summary>
		/// <typeparam name="REAL">代理类型。</typeparam>
		/// <param name="proxy">被代理的真实对象。</param>
		/// <returns>属性访问器代理。</returns>
		public static REAL GetProxy<REAL>(NameObjectCollectionBase proxy)
		{
			return (REAL)PropertiesProxy.GetProxy(typeof(REAL), proxy);
		}

		#endregion

		#region Set method delegate or invoke handler Or Get real proxy or accessor or propertity proxy or real object Or Has propertity key

		/// <summary>
		/// 设置属性访问器对象操作方法
		/// </summary>
		/// <param name="proxy">属性访问器对象</param>
		/// <param name="method">对象操作方法委托</param>
		/// <returns>是否成功，非零值为失败</returns>
		public static int SetMethod(object proxy, Delegate method)
		{
			return PropertiesProxy.SetMethod(proxy, method.Method, method);
		}

		/// <summary>
		/// 设置属性访问器对象操作方法
		/// </summary>
		/// <param name="proxy">属性访问器对象</param>
		/// <param name="method">要设置的方法</param>
		/// <param name="target">对象操作方法委托</param>
		/// <returns>是否成功，非零值为失败</returns>
		public static int SetMethod(object proxy, MethodInfo method, Delegate handler)
		{
			if (proxy == null)
				return -1;

			var pp = RemotingServices.GetRealProxy(proxy) as PropertiesProxy;
			if (pp == null)
				return 1;

			pp._Proxy[pp.GetMemberKey(null, method)] = handler;
			return 0;
		}

		/// <summary>
		/// 设置属性访问调用拦截委托。
		/// </summary>
		/// <param name="proxy">属性访问器对象</param>
		/// <param name="handler">属性访问调用拦截委托</param>
		/// <returns>是否成功，非零值为失败</returns>
		public static int SetInvokeHandler(object proxy, PropertiesProxyEventHandler handler)
		{
			if (proxy == null)
				return -1;

			var pp = RemotingServices.GetRealProxy(proxy) as PropertiesProxy;
			if (pp == null)
				return 1;

			pp._OnInvokeHandler = handler;
			return 0;
		}

		/// <summary>
		/// 获取真实代理对象
		/// </summary>
		/// <param name="proxy">属性访问器代理</param>
		/// <returns>真实代理对象</returns>
		public static object GetPropertiesReal(object proxy)
		{
			if (proxy == null)
				return null;

			var pp0 = RemotingServices.GetRealProxy(proxy);
			if (pp0 == null)
				return proxy;

			var pp1 = pp0 as PropertiesProxy;
			if (pp1 == null)
				return pp0;

			return pp1._Proxy.Real;
		}

		/// <summary>
		/// 获取真实代理对象
		/// </summary>
		/// <param name="proxy">属性访问器代理</param>
		/// <returns>真实代理访问器</returns>
		public static IPropertiesAccessor GetPropertiesAccessor(object proxy)
		{
			if (proxy == null)
				return null;

			var pp0 = RemotingServices.GetRealProxy(proxy);
			if (pp0 == null)
				return null;

			var pp1 = pp0 as PropertiesProxy;
			if (pp1 == null)
				return null;

			return pp1._Proxy;
		}

		/// <summary>
		/// 获取真实代理对象
		/// </summary>
		/// <param name="proxy">属性访问器代理</param>
		/// <returns>真实代理对象</returns>
		public static PropertiesProxy GetPropertiesProxy(object proxy)
		{
			if (proxy == null)
				return null;

			var pp = RemotingServices.GetRealProxy(proxy);
			if (pp == null)
				return null;

			return pp as PropertiesProxy;
		}

		/// <summary>
		/// 探测属性是否存在。
		/// </summary>
		/// <param name="proxy">代理对象。</param>
		/// <param name="key">属性键。</param>
		/// <returns>是否存在。</returns>
		public static bool HasProperty(object proxy, object key)
		{
			if (proxy == null)
				return false;

			var pp = RemotingServices.GetRealProxy(proxy) as PropertiesProxy;
			if (pp == null)
				return false;

			return pp._Proxy.Contains(pp.GetMemberKey(key, key));
		}

		#endregion

		#region For serialize

		/// <summary>
		/// 获取可序列化或反序列化对象。
		/// </summary>
		/// <param name="arg">代理实对象或透明代理对象。</param>
		/// <param name="onSerializing">是否正在准备序列化。</param>
		/// <returns>如果正在准备序列化，则返回真实对象，否则返回透明对象，如果不是代理相关对象，则返回空。</returns>
		public static object GetSerializableObject(object arg, bool onSerializing)
		{
			if (onSerializing)
			{
				if (arg is MarshalByRefObject)
					return RemotingServices.GetRealProxy(arg);// as PropertiesProxy;

				return null;
			}

			var rp = arg as RealProxy;
			if (rp == null)
				return null;

			return rp.GetTransparentProxy();
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="args">输入参数数组。</param>
		/// <param name="deserialize">反序列化内容，如果为空则表示正在或将要进行序列化，需要将透明代理转换成真实代理。</param>
		/// <returns>如果是正在或将要序列化，则返回真实代理数组，如果返回为空则表示输入参数数组中不存在透明代理数据。如果是反序列化，则返回输入参数。</returns>
		public static object GetSerializableObject(object[] args, object[] deserialize)
		{
			if (args == null || args.Length == 0)
				return null;

			var os = deserialize;
			if (os == null)//正在序列化。
			{
				os = new object[args.Length];
				for (var i = 0; i < args.Length; i++)
				{
					var item = args[i];
					if (item == null)
						continue;

					if (item is MarshalByRefObject)
					{
						item = RemotingServices.GetRealProxy(item);//序列化时，将透明代理转成真实代理。
						if (item != null)
						{
							args[i] = null;
							os[i] = item;
							deserialize = os;//表示存在代理参数，需要返回。
						}
					}
				}
				return deserialize;
			}

			for (var i = 0; i < deserialize.Length; i++)
			{
				var item = deserialize[i];
				if (item == null)
					continue;

				var pp = item as RealProxy;
				if (pp != null)
					args[i] = pp.GetTransparentProxy();//反序列化时，将真实代理转成透明代理。
			}
			return args;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="args">输入参数数组。</param>
		/// <param name="deserialize">反序列化内容，如果为空则表示正在或将要进行序列化，需要将透明代理转换成真实代理。</param>
		/// <returns>如果是正在或将要序列化，则返回真实代理数组，如果返回为空则表示输入参数数组中不存在透明代理数据。如果是反序列化，则返回输入参数。</returns>
		public static object GetSerializableObject(IList args, object[] deserialize)
		{
			if (args == null || args.Count == 0)
				return null;

			var os = deserialize;
			if (os == null)//正在序列化。
			{
				os = new object[args.Count];
				for (var i = 0; i < args.Count; i++)
				{
					var item = args[i];
					if (item == null)
						continue;

					if (item is MarshalByRefObject)
					{
						item = RemotingServices.GetRealProxy(item);//序列化时，将透明代理转成真实代理。
						if (item != null)
						{
							args[i] = null;
							os[i] = item;
							deserialize = os;//表示存在代理参数，需要返回。
						}
					}
				}
				return deserialize;
			}

			for (var i = 0; i < deserialize.Length; i++)
			{
				var item = deserialize[i];
				if (item == null)
					continue;

				var pp = item as RealProxy;
				if (pp != null)
					args[i] = pp.GetTransparentProxy();//反序列化时，将真实代理转成透明代理。
			}
			return args;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="args">输入参数数组。</param>
		/// <param name="deserialize">反序列化内容，如果为空则表示正在或将要进行序列化，需要将透明代理转换成真实代理。</param>
		/// <returns>如果是正在或将要序列化，则返回真实代理数组，如果返回为空则表示输入参数数组中不存在透明代理数据。如果是反序列化，则返回输入参数。</returns>
		public static object GetSerializableObject(IDictionary args, IDictionary deserialize)
		{
			if (args == null || args.Count == 0)
				return null;

			var os = deserialize;
			if (os == null)//正在序列化。
			{
				os = new Hashtable();
				foreach (var k in args.Keys)
				{
					var item = args[k];
					if (item == null)
						continue;

					if (item is MarshalByRefObject)
					{
						item = RemotingServices.GetRealProxy(item);//序列化时，将透明代理转成真实代理。
						if (item != null)
						{
							args[k] = null;
							os[k] = item;
							deserialize = os;//表示存在代理参数，需要返回。
						}
					}
				}
				return deserialize;
			}

			foreach (var k in deserialize.Keys)
			{
				var item = deserialize[k];
				if (item == null)
					continue;

				var pp = item as RealProxy;
				if (pp != null)
					args[k] = pp.GetTransparentProxy();//反序列化时，将真实代理转成透明代理。
			}
			return args;
		}

		/// <summary>
		/// 使用将目标对象序列化所需的数据填充 System.Runtime.Serialization.SerializationInfo。
		/// </summary>
		/// <param name="graph">要序列化的对象。</param>
		/// <param name="info">要填充数据的 System.Runtime.Serialization.SerializationInfo。</param>
		/// <param name="context">此序列化的目标（请参见 System.Runtime.Serialization.StreamingContext）。</param>
		/// <returns>闭包返回原要序列化的对象。</returns>
		/// <exception cref="System.Security.SecurityException">调用方没有所要求的权限。</exception>
		public static object Serialize(object graph, SerializationInfo info, StreamingContext context)
		{
			return Serialize(graph, info, context, false);
		}
		/// <summary>
		/// 使用将目标对象序列化所需的数据填充 System.Runtime.Serialization.SerializationInfo。
		/// </summary>
		/// <param name="graph">要序列化的对象。</param>
		/// <param name="info">要填充数据的 System.Runtime.Serialization.SerializationInfo。</param>
		/// <param name="context">此序列化的目标（请参见 System.Runtime.Serialization.StreamingContext）。</param>
		/// <param name="excludeNulOnlyl">是否仅排除空值得；默认排除所有默认值及空值；公排除空值可以提升序列化效率，但会增加序列化结果，如果序列化的内容在网络传输，则会增加网络负担。</param>
		/// <returns>闭包返回原要序列化的对象。</returns>
		/// <exception cref="System.Security.SecurityException">调用方没有所要求的权限。</exception>
		public static object Serialize(object graph, SerializationInfo info, StreamingContext context, bool excludeNulOnlyl)
		{
			if (graph == null)
				return null;

			var key = new List<string>();
			var guid = Guid.NewGuid().ToString();
			var table = new Hashtable();
			var generation = 0;
			var type = graph.GetType();
			table.Add(graph, guid);
			info.AddValue(string.Empty, guid);
			if (string.IsNullOrEmpty(info.AssemblyName) && string.IsNullOrEmpty(info.FullTypeName))
				info.SetType(type);
			var fs = type.GetAllFields();// type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);// | BindingFlags.DeclaredOnly | BindingFlags.Static);
			var fl = fs.Length; //fs.Count; //
			while (type != null)
			{
				//var fs = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);// | BindingFlags.Static);
				//foreach (var f in fs)//成员字段的序列化。
				for (var fi = 0; fi < fl; fi++)
				{
					var f = fs[fi];
					if (f == null || f.DeclaringType != type)
						continue;

					fs[fi] = null;
					if (f.IsStatic || f.GetCustomAttributes(typeof(NonSerializedAttribute), false).Length != 0)
						continue;

					var value = f.GetValue(graph);
					if (value == null)
						continue;

					if (!excludeNulOnlyl && value.Equals(f.FieldType.GetDefault()))
						continue;

					var name = AsciiChar.VT + f.Name;
					name = generation + name;
					if (table.ContainsKey(value))//如果是重复引用。
					{
						key.Add(name);
						key.Add(name + AsciiChar.LF);//LF 引用重定向。
						info.AddValue(name + AsciiChar.LF, guid + AsciiChar.HT + table[value]);
						continue;
					}

					table.Add(value, name);
					if (value is MarshalByRefObject)// && f.FieldType != typeof(string) && !f.FieldType.IsValueType
					{
						var proxy = RemotingServices.GetRealProxy(value);
						if (proxy != null)
						{
							value = proxy;
							key.Add(name + AsciiChar.CR);//CR 代理重定向。
							info.AddValue(name + AsciiChar.CR, proxy.GetType());
						}
					}

					#region 可枚举对象内部元素处理。

					if (value is object[])//object[]
					{
						var n = string.Empty;
						var os = value as object[];
						var vs = new object[os.Length];
						for (var i = 0; i < os.Length; i++)
						{
							var item = os[i];
							if (item is MarshalByRefObject)
							{
								item = RemotingServices.GetRealProxy(item);
								if (item != null)
								{
									os[i] = null;
									vs[i] = item;
									n = name + AsciiChar.VT;
								}
							}
						}
						if (n != string.Empty)
							info.AddValue(n, vs);
					}

					if (value is IList)//IList
					{
						var n = string.Empty;
						var ls = value as IList;
						var vs = new object[ls.Count];
						for (var i = 0; i < ls.Count; i++)
						{
							var item = ls[i];
							if (item is MarshalByRefObject)
							{
								item = RemotingServices.GetRealProxy(item);
								if (item != null)
								{
									ls[i] = null;
									vs[i] = item;
									n = name + AsciiChar.VT;
								}
							}
						}
						if (n != string.Empty)
							info.AddValue(n, vs);
					}

					if (value is IDictionary)//IDictionary
					{
						var n = string.Empty;
						var ds = value as IDictionary;
						var vs = new Hashtable();//ds.Count
						foreach (var k in ds.Keys)
						{
							var item = ds[k];
							if (item is MarshalByRefObject)
							{
								item = RemotingServices.GetRealProxy(item);
								if (item != null)
								{
									ds[k] = null;
									vs[k] = item;
									n = name + AsciiChar.VT;
								}
							}
						}
						if (n != string.Empty)
							info.AddValue(n, vs);
					}

					#endregion

					key.Add(name);
					info.AddValue(name, value);
				}
				generation++;
				type = type.BaseType;
			}
			//info.AddValue(guid, key.ToArray);
			return graph;
		}

		/// <summary>
		/// 使用将 System.Runtime.Serialization.SerializationInfo 对象反序列化所需的数据填充目标。
		/// </summary>
		/// <param name="graph">要反序列化还原的对象。</param>
		/// <param name="info">可获取已序列化数据的 System.Runtime.Serialization.SerializationInfo。</param>
		/// <param name="context">此反序列化的来源（请参见 System.Runtime.Serialization.StreamingContext）。</param>
		/// <exception cref="System.Security.SecurityException">调用方没有所要求的权限。</exception>
		public static object Deserialize(object graph, SerializationInfo info, StreamingContext context)
		{
			if (graph == null || info.MemberCount == 0)
				return null;

			try
			{
				var type = graph.GetType();
				var guid = info.GetValue(string.Empty, typeof(object)) + string.Empty;
				var key = new List<string>(info.MemberCount);
				var sie = info.GetEnumerator();
				while (sie.MoveNext())
					key.Add(sie.Name);
				//var key = new List<string>(info.GetValue(guid, typeof(object)) as IEnumerable<string>);
				var fs = type.GetAllFields();// type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);// | BindingFlags.DeclaredOnly | BindingFlags.Static);
				var fl = fs.Length; //fs.Count; //
				var generation = 0;
				while (type != null)
				{
					//var fs = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);// | BindingFlags.Static);
					//foreach (var f in fs)
					for (var fi = 0; fi < fl; fi++)
					{
						var f = fs[fi];
						if (f == null || f.DeclaringType != type)
							continue;

						fs[fi] = null;
						if (f.IsStatic)
							continue;

						var name = AsciiChar.VT + f.Name;
						name = generation + name;
						if (key.Contains(name + AsciiChar.LF))//存在引用重定向。
						{
							var t = info.GetValue(name + AsciiChar.LF, typeof(object)) as string;
							if (!string.IsNullOrEmpty(t))
							{
								var ts = t.Split(new char[] { AsciiChar.CR, AsciiChar.LF, AsciiChar.HT }, StringSplitOptions.RemoveEmptyEntries);
								if (ts != null && ts.Length == 2 && ts[0] == guid)//guid,key,type,assembly
								{
									if (ts[1] == guid)
									{
										f.SetValue(graph, graph);//自身引用。
										continue;
									}

									name = ts[1];
								}
							}
						}

						if (!key.Contains(name))
							continue;

						var ft = f.FieldType;
						if (key.Contains(name + AsciiChar.CR))//存在代理重定向。
							ft = info.GetValue(name + AsciiChar.CR, typeof(Type)) as Type;
						var value = info.GetValue(name, typeof(object));//ft
						if (ft != f.FieldType)
						{
							var rp = value as RealProxy;
							if (rp != null)
								value = rp.GetTransparentProxy();
						}

						#region 可枚举对象内部元素处理。

						if (value is object[] && key.Contains(name + AsciiChar.VT))//object[]
						{
							var os = value as object[];
							var vs = info.GetValue(name + AsciiChar.VT, typeof(object)) as object[];
							for (var i = 0; i < vs.Length; i++)
							{
								if (vs[i] == null)
									continue;

								var item = vs[i] as RealProxy;
								os[i] = item.GetTransparentProxy();
							}
						}

						if (value is IList && key.Contains(name + AsciiChar.VT))//IList
						{
							var ls = value as IList;
							var vs = info.GetValue(name + AsciiChar.VT, typeof(object)) as object[];
							for (var i = 0; i < vs.Length; i++)
							{
								if (vs[i] == null)
									continue;

								var item = vs[i] as RealProxy;
								ls[i] = item.GetTransparentProxy();
							}
						}

						if (value is IDictionary && key.Contains(name + AsciiChar.VT))//IDictionary
						{
							var ds = value as IDictionary;
							var vs = info.GetValue(name + AsciiChar.VT, typeof(object)) as IDictionary;
							foreach (var k in vs.Keys)
							{
								var item = vs[k] as RealProxy;
								ds[k] = item.GetTransparentProxy();
							}
						}

						#endregion

						f.SetValue(graph, value);
					}
					generation++;
					type = type.BaseType;
				}
			}
			catch (Exception x)
			{
				PickGold.Common.LastError = x;
			}
			return graph;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		public static ISurrogateSelector GetSurrogateSelector()
		{
			return new SurrogateSelector();
		}

		#endregion
	}

	[DataContract]
	[Serializable]
	[ComVisible(true)]
	class CMessage : IMethodMessage
	{
		/// <summary>
		/// 执行方线程对象
		/// </summary>
		[ThreadStatic]
		public static object ThreadHandler;

		/// <summary>
		/// 执行方线程数据
		/// </summary>
		[ThreadStatic]
		public static IMethodMessage ThreadMessage;

		public static object SetThreadData(IMethodMessage message, IDictionary<string, object> items)
		{
			if (message == null)
				return null;

			if (items == null)
				return null;

			foreach (var key in items.Keys)
				message.LogicalCallContext.SetData(key, items[key]);
			CMessage.ThreadMessage = message;
			return message;
		}

		public static object SetThreadData(IDictionary<string, object> items)
		{
			if (items == null)
				return null;

			if (CMessage.ThreadMessage == null)
				return null;

			foreach (var key in items.Keys)
				CMessage.ThreadMessage.LogicalCallContext.SetData(key, items[key]);
			return items;
		}

		public static object SetThreadData(string name, object data)
		{
			if (CMessage.ThreadMessage == null)
				return null;

			CMessage.ThreadMessage.LogicalCallContext.SetData(name, data);
			return data;
		}

		public static object GetThreadData(string name)
		{
			if (CMessage.ThreadMessage == null)
				return null;

			return CMessage.ThreadMessage.LogicalCallContext.GetData(name);
		}

		public static object[] ProcessPropertiesProxy(object[] args, object[] deserialize)
		{
			if (args == null || args.Length == 0)
				return null;

			var ps = deserialize;
			if (ps == null)//正在序列化。
			{
				#region 正在序列化

				ps = new object[args.Length];
				for (var i = 0; i < args.Length; i++)
				{
					var item = args[i];
					if (item == null)
						continue;

					item = PropertiesProxy.GetSerializableObject(item, true);//正在序列化。
					if (item != null)
					{
						args[i] = item;
						continue;
					}

					var os = args[i] as object[];
					if (os != null)
					{
						item = PropertiesProxy.GetSerializableObject(os, null);
						if (item != null)//不返回空表示存在透明代理，已转换。
						{
							ps[i] = item;
							deserialize = ps;//表示存在代理参数，需要返回。
						}
						continue;
					}

					var ls = args[i] as IList;
					if (ls != null)
					{
						item = PropertiesProxy.GetSerializableObject(ls, null);
						if (item != null)//不返回空表示存在透明代理，已转换。
						{
							ps[i] = item;
							deserialize = ps;//表示存在代理参数，需要返回。
						}
						continue;
					}

					var ds = args[i] as IDictionary;
					if (ds != null)
					{
						item = PropertiesProxy.GetSerializableObject(ds, null);
						if (item != null)//不返回空表示存在透明代理，已转换。
						{
							ps[i] = item;
							deserialize = ps;//表示存在代理参数，需要返回。
						}
						continue;
					}
				}

				#endregion

				return deserialize;//ps，返回，正在序列化。
			}

			for (var i = 0; i < deserialize.Length; i++)
			{
				var item = deserialize[i];
				if (item == null)
					continue;

				item = PropertiesProxy.GetSerializableObject(item, false);//正在反序列化。
				if (item != null)
				{
					args[i] = item;
					continue;
				}

				var os = args[i] as object[];
				if (os != null)
				{
					PropertiesProxy.GetSerializableObject(os, deserialize[i] as object[]);
					continue;
				}

				var ls = args[i] as IList;
				if (ls != null)
				{
					PropertiesProxy.GetSerializableObject(ls, deserialize[i] as object[]);
					continue;
				}

				var ds = args[i] as IDictionary;
				if (ds != null)
				{
					PropertiesProxy.GetSerializableObject(ds, deserialize[i] as IDictionary);
					continue;
				}
			}
			return args;
		}

		public virtual void ProcessPropertiesProxy(bool onSerializing)
		{
			if (this.Args == null || this.Args.Length == 0)
				return;

			if (onSerializing)//如果正在序列化。
				this.ProxyArgs = CMessage.ProcessPropertiesProxy(this.Args, null);

			if (this.ProxyArgs == null || this.ProxyArgs.Length == 0)//反序列化，如果不存在真实代理
				return;

			CMessage.ProcessPropertiesProxy(this.Args, this.ProxyArgs);
		}

		public object[] Args;

		public string[] ArgNames;

		public LogicalCallContext LogicalCallContext;

		public MethodBase MethodBase;

		public string MethodName;

		public object MethodSignature;

		public string TypeName;

		public string Uri;

		public IDictionary Properties;

		private object[] ProxyArgs;

		#region IMethodMessage

		int IMethodMessage.ArgCount
		{
			get
			{
				if (this.Args == null)
					return 0;

				return this.Args.Length;
			}
		}

		object[] IMethodMessage.Args
		{
			get
			{
				return this.Args;
			}
		}

		object IMethodMessage.GetArg(int argNum)
		{
			return this.Args[argNum];
		}

		string IMethodMessage.GetArgName(int index)
		{
			return this.ArgNames[index];
		}

		bool IMethodMessage.HasVarArgs
		{
			get { throw new NotImplementedException(); }
		}

		LogicalCallContext IMethodMessage.LogicalCallContext
		{
			get
			{
				return this.LogicalCallContext;
			}
		}

		MethodBase IMethodMessage.MethodBase
		{
			get
			{
				return this.MethodBase;
			}
		}

		string IMethodMessage.MethodName
		{
			get
			{
				return this.MethodName;
			}
		}

		object IMethodMessage.MethodSignature
		{
			get
			{
				return this.MethodSignature;
			}
		}

		string IMethodMessage.TypeName
		{
			get
			{
				return this.TypeName;
			}
		}

		string IMethodMessage.Uri
		{
			get
			{
				return this.Uri;
			}
		}

		IDictionary IMessage.Properties
		{
			get
			{
				return this.Properties;
			}
		}

		#endregion
	}
}
